package com.alks.common.utils;

import com.alks.entity.exception.InDataException;
import com.alks.entity.exception.ServiceErrorException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 时间工具类
 *
 * @author Tan
 */

@Slf4j
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    public static String YYYY = "yyyy";

    public static String YYYYMM = "yyyyMM";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static String getMonth(Date date) {
        return parseDateToStr(YYYY_MM, date);
    }
    public static String getMonth1(Date date) {
        return parseDateToStr(YYYYMM, date);
    }

    public static String getYear(Date date) {
        return parseDateToStr(YYYY, date);
    }
    public static final String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String dateTimeNow() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date) {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    private final static SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
    public static final String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static final Date dateTime(final String format, final String ts) {
        try {
            return new SimpleDateFormat(format).parse(ts);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String dateTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }
    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String monthTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMM");
    }
    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String yearTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy");
    }
    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算相差多少分钟
     *
     * @param endDate 结束日期
     * @param nowDate 现在日期
     * @return {@link BigDecimal}
     */
    public static BigDecimal getDifferenceMinutes(Date endDate, Date nowDate){
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少分钟
        long min = diff % nd % nh / nm;
        return new BigDecimal(min);
    }

    /**
     * 获得分钟
     * 时间戳转分钟
     *
     * @param time 时间
     * @return {@link BigDecimal}
     */
    public static BigDecimal getMinutes(Long time){
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
// 计算差多少分钟
        long min = time % nd % nh / nm;
        return new BigDecimal(min);
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    /**
     * 增加 LocalDateTime ==> Date
     */
    public static Date toDate(LocalDateTime temporalAccessor) {
        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    /**
     * 增加 LocalDate ==> Date
     */
    public static Date toDate(LocalDate temporalAccessor) {
        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }


    /**
     * 流程完成时间处理
     *
     * @param ms 参数
     */
    public static String getProcessCompletionTime(long ms) {
        long day = ms / (24 * 60 * 60 * 1000);
        long hour = (ms / (60 * 60 * 1000) - day * 24);
        long minute = ((ms / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long second = (ms / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60);

        if (day > 0) {
            return day + "天" + hour + "小时" + minute + "分钟";
        }
        if (hour > 0) {
            return hour + "小时" + minute + "分钟";
        }
        if (minute > 0) {
            return minute + "分钟";
        }
        if (second > 0) {
            return second + "秒";
        } else {
            return 0 + "秒";
        }
    }

    /**
     * 获取年月yyyy-MM
     *
     * @return
     */
    public static List<String> getMonthData() {
        List<String> monthList = new ArrayList<>();
        int year = LocalDateTime.now().getYear();
        for (int i = 1; i < 13; i++) {
            if (i < 10) {
                monthList.add(year + "-0" + i);
            } else {
                monthList.add(year + "-" + i);
            }
        }
        return monthList;
    }

    /**
     * 获取某年第一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getFirstOfYear(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        return calendar.getTime();
    }
    /**
     *  时间转时间字符串
     * @param date  日期
     * @param pattern  格式
     * @return String
     */
    public static String format(Date date, String pattern) {
        if (date == null)
            return "";
        return DateFormatUtils.format(date, pattern);
    }

    /**
     *  时间转时间字符串为yyyy-MM-dd HH:mm:ss 格式
     * @param date  日期
     * @return String
     */
    public static String formatDateTime(Date date) {
        if (date == null)
            return "";
        return DateFormatUtils.format(date, YYYY_MM_DD);
    }

    public static Date getToDay() {
        Date now = new Date();
        String format = DateFormatUtils.format(now, YYYY_MM_DD);
        Date date = parseDateTime(format);
        return date;
    }
    /**
     *  时间字符串转化为yyyy-MM-dd HH:mm:ss 格式
     * @param str  日期
     * @return Date
     */
    public static Date parseDateTime(String str) {
        if (str == null)
            return null;
        try {
            return DateUtils.parseDate(str, YYYY_MM_DD);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *  字符串转时间
     * @param str  字符串
     * @param dateTimePattern  格式
     * @return Date
     */
    public static Date parseDateTime(String str, String dateTimePattern) {
        if (str == null)
            return null;
        try {
            return DateUtils.parseDate(str, Locale.CHINESE, dateTimePattern);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 获取当年的第一天
     */
    public static String getCurrentFirstOfYear(){
        Calendar currCal=Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return formatDateTime(getFirstOfYear(currentYear));
    }

    /**
     * 获取当年的最后一天
     */
    public static Date getCurrentLastOfYear() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getLastOfYear(currentYear);

    }
    /**
     * 获取某年最后一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getLastOfYear(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTime();
    }
    /**
     * 获取上一个月1号0点0分0秒的时间
     */
    public static Date getBeforeFirstMonthdate(){
        SimpleDateFormat format=new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
        Calendar calendar=Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        //将小时至00
        calendar.set(Calendar.HOUR_OF_DAY, 00);
        //将分钟至00
        calendar.set(Calendar.MINUTE, 00);
        //将秒至00
        calendar.set(Calendar.SECOND,00);
//        String format1 = format.format(calendar.getTime());
        return calendar.getTime();
    }

    /**
     * 获得本月的开始时间
     *
     * @return
     */
    public static Date getCurrentMonthStartTime(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            now = shortSdf.parse(shortSdf.format(c.getTime()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }
    /**
     * 获取本年度的十二个月份 yyyyMM
     * @param yearMonth
     * @return
     */
    public static List<String> getMonthByYear(String yearMonth){
        List<String> data = new ArrayList<>();
        try {
            Calendar c = Calendar.getInstance();
            // 获取当前的年份
            int year = c.get(Calendar.YEAR);
            // 定义时间格式
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
            // 开始日期为当前年拼接1月份
            Date startDate = sdf.parse(year + "01");
            // 结束日期为当前年拼接12月份
            Date endDate = sdf.parse(year + "12");
            // 设置calendar的开始日期
            c.setTime(startDate);
            // 当前时间小于等于设定的结束时间
            while(c.getTime().compareTo(endDate) <= 0){
                if (sdf.parse(yearMonth).after(c.getTime()) || sdf.parse(yearMonth).equals(c.getTime())){
                    String time = sdf.format(c.getTime());
                    data.add(time);
                }

                // 当前月份加1
                c.add(Calendar.MONTH, 1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 遍历本月度的每一天 yyyyMMdd
     * @param monthDay 截至日期
     * @return
     */
    public static List<String> getDayByMonth(String monthDay){
        List<String> data = new ArrayList<>();
        try {
            Calendar c = Calendar.getInstance();
            // 获取当前的年份
            int year = c.get(Calendar.YEAR);
            // 获取当前的月份（需要加1才是现在的月份）
            int month = c.get(Calendar.MONTH) + 1;
            // 获取本月的总天数
            int dayCount = c.getActualMaximum(Calendar.DAY_OF_MONTH);
            // 定义时间格式
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // 开始日期为当前年月拼接1号
            String mth = "";
            if (month>9){
                mth = String.valueOf(month);
            }else {
                mth = "0" +  month;
            }
            Date startDate = sdf.parse(year  +  mth + "01");
            // 结束日期为当前年月拼接该月最大天数
            Date endDate = sdf.parse(year + mth + dayCount);
            // 设置calendar的开始日期
            c.setTime(startDate);
            // 当前时间小于等于设定的结束时间
            while(c.getTime().compareTo(endDate) <= 0){
                if (sdf.parse(monthDay).after(c.getTime()) || sdf.parse(monthDay).equals(c.getTime())){
                    String time = sdf.format(c.getTime());
                    data.add(time);
                }
                // 当前日期加1
                c.add(Calendar.DATE, 1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return data;
    }

    /**
     * 遍历本周的所有日期 yyyyMMdd
     * @param week 截至日期
     * @return
     */
    public static List<String> getDayByWeek(String week){
        List<String> data = new ArrayList<>();
        try {
            //获取本周时间
            String yzTime = getTimeInterval(new Date());
            String[] time = yzTime.split(",");
            //本周第一天
            String startTime = time[0];
            //本周最后一天
            String endTime = time[1];
            //格式化日期
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            Date dBegin = sdf.parse(startTime);
            Date dEnd = sdf.parse(endTime);
            //获取这周所有date
            List<Date> lDate = findDates(dBegin, dEnd);
            for (Date date : lDate) {
                if (sdf.parse(week).after(date) || sdf.parse(week).equals(date)){
                    data.add(sdf.format(date));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return data;
    }

    // 根据指定日期获取一周的第一天和最后一天日期
    public static String getTimeInterval(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String imptimeBegin = sdf.format(cal.getTime());
        cal.add(Calendar.DATE, 6);
        String imptimeEnd = sdf.format(cal.getTime());
        return imptimeBegin + "," + imptimeEnd;
    }


    /**
     * 查找日期
     * @param dBegin 开始日期
     * @param dEnd 结束日期
     * @return List<Date>
     */
    public static List<Date> findDates(Date dBegin, Date dEnd) {
        List<Date> lDate = new ArrayList<>();
        lDate.add(dBegin);
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime())){
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            lDate.add(calBegin.getTime());
        }
        return lDate;
    }

    /**
     * 获取当月的所有周末
     * @param year
     * @param month
     * @return
     */
    public static List<String> getWeekendInMonth(int year, int month) {
        List<String> dateList=new ArrayList<>();
        SimpleDateFormat simdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);// 不设置的话默认为当年
        calendar.set(Calendar.MONTH, month - 1);// 设置月份
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为当月第一天
        int daySize = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);// 当月最大天数
        for (int i = 0; i < daySize; i++) {
            int week = calendar.get(Calendar.DAY_OF_WEEK);
            if (week == Calendar.SATURDAY ) {// 1代表周日，7代表周六 判断这是一个星期的第几天从而判断是否是周末
                dateList.add(simdf.format(calendar.getTime()));
            }
            if (week == Calendar.SUNDAY) {// 1代表周日，7代表周六 判断这是一个星期的第几天从而判断是否是周末
                dateList.add(simdf.format(calendar.getTime()));
            }
            calendar.add(Calendar.DATE, 1);//在第一天的基础上加1
        }
        return dateList;
    }

    /**
     * 根据年月获取周末日期 列如202404
     * @param years
     * @return [2024-03-02, 2024-03-03, 2024-03-09, 2024-03-10, 2024-03-16, 2024-03-17, 2024-03-23, 2024-03-24, 2024-03-30, 2024-03-31]
     */
    public static String[] getYearMonth(String years) {
        String regex = "(\\d{4})(\\d{2})";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(years);
        if (matcher.matches()) {
            String year = matcher.group(1);
            String month = matcher.group(2);
            return new String[]{year, month};
        } else {
            return null;
        }
    }

    /**
     * 根据年月获取周末日
     * @param year
     * @param month
     * @return
     */
    public static List<Integer> getWeekendDays(int year, int month) {
        List<Integer> weekendDays = new ArrayList<>();
        // 获取指定年月的第一天
        LocalDate date = LocalDate.of(year, month, 1);
        // 获取该月的天数
        int daysInMonth = date.lengthOfMonth();
        // 循环遍历该月的每一天
        for (int day = 1; day <= daysInMonth; day++) {
            // 获取当前日期的对象
            LocalDate currentDate = LocalDate.of(year, month, day);
            // 判断当前日期是否为周六或周日
            if (currentDate.getDayOfWeek() == DayOfWeek.SATURDAY ||
                    currentDate.getDayOfWeek() == DayOfWeek.SUNDAY) {
                weekendDays.add(day);
            }
        }
        return weekendDays;
    }

    /**
     * 判断字符串是否为日期格式
     * @param str
     * @return
     */
    public static boolean isValidDateFormat(String str) {
        // 使用正则表达式匹配年月日格式：YYYY-MM-DD
        String regex = "\\d{4}-\\d{2}-\\d{2}";
        // 编译正则表达式
        Pattern pattern = Pattern.compile(regex);
        // 创建匹配器对象
        Matcher matcher = pattern.matcher(str);
        // 返回是否匹配成功
        return matcher.matches();
    }

    /**
     * 检查 年月格式是否正确
     * @param input
     * @return
     */
    public static boolean isValidYearMonth(String input) {
        String pattern = "^\\d{4}\\d{2}$";
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMM");
        if (!input.matches(pattern)) {
            return false;
        }
        dateFormat.setLenient(false);
        try {
            dateFormat.parse(input);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 结算日期检核（日期只能是最近一年的数据）
     * @param financeYymm
     * @return
     */
    public static void financeYymmCheck(String financeYymm) {
        YearMonth financeRec;
        try {
            financeRec = YearMonth.parse(financeYymm, DateTimeFormatter.ofPattern("yyyyMM"));
        } catch (DateTimeParseException e) {
            throw new InDataException("时间格式异常");
        }
        //早于当前一年或者晚于当前时间不能检核
        if (financeRec.isBefore(YearMonth.now().minusYears(1)) || financeRec.isAfter(YearMonth.now())) {
            StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
            String callingMethodName = stackTraceElements[2].getMethodName();
            log.warn("异常接口：{}\n异常原因：早于当前一年或者晚于当前时间不能结算\n当前输入检核时间：{}\n", callingMethodName,financeYymm);
            throw new ServiceErrorException("结算月份有误");
        }
    }

    /**
     * 根据年月计算当前年月天数
     * @param years
     * @return
     */
    public static int getDaysInMonth(String  years) {
        String[] yearMonth = getYearMonth(years);
        String year = yearMonth[0];
        String month = yearMonth[1];
        LocalDate date = LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), 1);
        return date.lengthOfMonth();
    }

    /**
     * 根据年月获取当前年月第一天
     * @param years
     * @return
     */
    public static LocalDate  getFirstDayInMonth(String  years) {
        String[] yearMonth = getYearMonth(years);
        String year = yearMonth[0];
        String month = yearMonth[1];
        YearMonth yearToMonth = YearMonth.of(Integer.parseInt( year), Integer.parseInt(month) );
        LocalDate firstDay = yearToMonth.atDay(1);
        return firstDay;
    }

    /**
     * 根据年月获取当前年月最后一天
     * @param years
     * @return
     */
    public static LocalDate  getLastDayInMonth(String  years) {
        String[] yearMonth = getYearMonth(years);
        String year = yearMonth[0];
        String month = yearMonth[1];
        YearMonth yearToMonth = YearMonth.of(Integer.parseInt( year), Integer.parseInt(month) );
        LocalDate lastDay = yearToMonth.atEndOfMonth();
        return lastDay;
    }

    /**
     * 获取对应时间所在月份的长度
     * @param time 指定时间
     * @return 对应月份长度
     */
    public static int getLengthOfMonth(LocalDateTime time) {
        LocalDate date = time.toLocalDate();
        return getLengthOfMonth(date);
    }

    public static int getLengthOfMonth(LocalDate time) {
        LocalDate lastDayOfMonth = time.with(TemporalAdjusters.lastDayOfMonth());
        return lastDayOfMonth.getDayOfMonth();
    }

    /**
     *获得当月的周日天数
     * @param date 指定时间
     * @return 周日天数
     */
    public static int getSundayCount(LocalDateTime date) {
        LocalDate localDate = date.toLocalDate();
        LocalDate startDay = localDate.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth());
        return getSundayCount(startDay, lastDay);
    }

    /**
     * 获取指定时间段内周日天数
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @return 周日天数
     */
    public static int getSundayCount(LocalDate startDate, LocalDate endDate) {
        int count = 0;
        LocalDate current = startDate;
        while (!current.isAfter(endDate)) {
            if (current.getDayOfWeek() == DayOfWeek.SUNDAY) {
                count++;
            }
            current = current.plusDays(1);
        }
        return count;
    }

    /**
     * 获取当月第一天
     * @param date 时间
     * @return 当月第一天
     */
    public static LocalDateTime getFirstDayOfMonth(LocalDateTime date) {
        LocalDate localDate = date.toLocalDate();
        return localDate.with(TemporalAdjusters.firstDayOfMonth()).atStartOfDay();
    }

    /**
     * 获取当月最后一天
     * @param date 时间
     * @return 当月第一天
     */
    public static LocalDateTime getLastDayOfMonth(LocalDateTime date) {
        LocalDate localDate = date.toLocalDate();
        return localDate.with(TemporalAdjusters.lastDayOfMonth()).atStartOfDay();
    }

    /**
     * 获取当月的每一天
     * @param date
     * @return
     */
    public static List<Integer> getDaysOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        // 获取当前月份
        int month = calendar.get(Calendar.MONTH);
        // 获取当前年份
        int year = calendar.get(Calendar.YEAR);

        // 获取当月的天数
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        // 创建号数集合
        List<Integer> days = new ArrayList<>();
        for (int i = 1; i <= daysInMonth; i++) {
            days.add(i);
        }

        return days;
    }

    public static int getDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH); // 获取当前日期是几号
    }


    public static void main(String[] args) {
        SimpleDateFormat format=new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
//        Date currentYearStart = getCurrentFirstOfYear();
//        System.out.println(formatDateTime(currentYearStart));

        Date currentYearEnd = getCurrentLastOfYear();
        System.out.println(formatDateTime(currentYearEnd));
        System.out.println(format.format(getBeforeFirstMonthdate()));
        List<String> monthByYear = getMonthByYear("202305");
        List<String> dayByWeek = getDayByWeek("20230510");
        List<String> dayByMonth = getDayByMonth("20230510");
        System.out.println(dayByMonth);
    }


    /**
     * 根据 yyyyMM 格式的月份信息获取指定年月的全部日期
     * @param month yyyyMM 格式的月份信息
     * @return 指定年月的全部日期列表
     */
    public static List<LocalDateTime> getDatesInMonth(String month) {
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
        // 解析 yyyyMM 字符串为 YearMonth 对象
        YearMonth yearMonth = YearMonth.parse(month, formatter);
        // 获取指定年月的第一天和最后一天
        LocalDateTime firstDay = yearMonth.atDay(1).atStartOfDay();
        LocalDateTime lastDay = yearMonth.atEndOfMonth().atStartOfDay();
        // 创建一个列表来存储日期
        List<LocalDateTime> dates = new ArrayList<>();
        // 遍历指定年月的每一天并添加到列表中
        LocalDateTime currentDate = firstDay;
        while (!currentDate.isAfter(lastDay)) {
            dates.add(currentDate);
            currentDate = currentDate.plusDays(1);
        }
        return dates;
    }

}
